#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from sys import argv, exit
from lib.opdefparse import *
from collections import deque

# Dummy object for easy opcode handling :D
class opcode:
	pass

class SVM:
	def __init__(self):
		self.stack = deque()
		self.IP = 0

	def runByteCode(self, code):
		while self.IP < len(code):
			op = code[self.IP]
			if op == opcode.NOP:
				print("NOP - no harm was done to any pet")
			elif op == opcode.PUSH:
				self.IP += 1 # Skip to the data
				print("PUSH " + hex(code[self.IP]) )
				self.stack.append(bytes([code[self.IP]]))
			elif op == opcode.RROT:
				print("RROT")
				self.stack.rotate(1)
			elif op == opcode.LROT:
				print("LROT")
				self.stack.rotate(-1)
			else:
				print("Unknown opcode:", repr(op))
				break
			self.IP += 1

if __name__ == '__main__':
	if len(argv) != 2:
		print('Usage: %s <bytecodefile>' % argv[0])
		sys.exit(1)
		
	# do magic stuff
	fh = open('lib/opcodes.def')
	for mnemonic, op in parseOpcodeDef(fh.read()):
		op = int(op,16)
		setattr(opcode, mnemonic, op)
	fh.close()

	svm = SVM()
	svm.runByteCode(open(argv[1],'rb').read())
	